import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.example.comment.base.dto.CommentAddDTO
import com.example.comment.base.dto.CommentQueryDTO
import com.example.comment.base.dto.CommentRemoveDTO
import com.example.comment.base.entity.Comment
import com.example.comment.enums.AuditStatusEnum
import com.example.comment.enums.CommentTypeEnum
import com.example.comment.repository.CommentRepository
import com.example.comment.service.CommentLikeService
import com.example.comment.service.impl.CommentServiceImpl
import com.example.comment.utils.SystemException
import spock.lang.Specification

import java.text.SimpleDateFormat


/**
 * @author QingZeyu
 * @date 2024/5/7 18:36
 */
class CommentService extends Specification {
    CommentRepository commentRepository = Mock(CommentRepository)

    CommentLikeService commentLikeService = Mock(CommentLikeService)

    def service = new CommentServiceImpl(commentRepository:commentRepository,commentLikeService:commentLikeService)
    def referenceId = 30L
    def "page 一条评论，一条回复，无点赞"(){
        given:
        def dto = new CommentQueryDTO()
        dto.setPage(1);
        dto.setSize(10);
        dto.setReferenceId(referenceId)
        dto.setUserId(5L)
        def comment = this.getComment(1L, 1L, 2L, null, referenceId)
        def replyComment = this.getReplyComment(2L, 2L, 1L, comment.getId(), referenceId)
        def page = new Page<Comment>()
        page.setTotal(1)
        page.setRecords([comment])
        def replyPage = new Page<Comment>()
        replyPage.setTotal(1)
        replyPage.setRecords([replyComment])
        commentRepository.page(dto) >> page
        commentRepository.getReplyComment(_ as Long,1,3) >> replyPage
        commentLikeService.isLike(1, 1) >> true
        commentLikeService.checkIfLike(_ as Long,_ as Long,referenceId) >> false
        commentLikeService.getLikeSize(_ as Long,referenceId) >> 0L
        when:
        def result = service.page(dto)
        then:
        result.getRecords().size() == 1
        result.getRecords().get(0).getLikeFlag() == false
        result.getRecords().get(0).getLikeSize() == 0
        result.getRecords().get(0).getReplyList().getRecords().size() ==1
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeFlag() == false
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeSize() == 0
    }

    def "page 一条评论，一条回复，父评论被删除"(){
        given:
        def dto = new CommentQueryDTO()
        dto.setPage(1);
        dto.setSize(10);
        dto.setReferenceId(referenceId)
        dto.setUserId(5L)
        def comment = this.getComment(1L, 1L, 2L, null, referenceId)
        def replyComment = this.getReplyComment(2L, 2L, 1L, comment.getId(), referenceId)
        def page = new Page<Comment>()
        page.setTotal(0)
        page.setRecords([])
        def replyPage = new Page<Comment>()
        replyPage.setTotal(1)
        replyPage.setRecords([replyComment])
        commentRepository.page(dto) >> page
        commentRepository.getReplyComment(_ as Long,1,3) >> replyPage
        commentLikeService.isLike(1, 1) >> true
        commentLikeService.checkIfLike(_ as Long,_ as Long,referenceId) >> false
        commentLikeService.getLikeSize(_ as Long,referenceId) >> 0L
        when:
        def result = service.page(dto)
        then:
        result.getRecords().size() == 0
        result.getTotal() == 0
    }

    def "page 一条评论，一条回复，评论有点赞且不是当前用户点赞，回复无点赞"(){
        def likeSize = 30L
        given:
        def dto = new CommentQueryDTO()
        dto.setPage(1);
        dto.setSize(10);
        dto.setReferenceId(referenceId)
        dto.setUserId(5L)
        def comment = this.getComment(1L, 1L, 2L, null, referenceId)
        def replyComment = this.getReplyComment(2L, 2L, 1L, comment.getId(), referenceId)
        def page = new Page<Comment>()
        page.setTotal(1)
        page.setRecords([comment])
        def replyPage = new Page<Comment>()
        replyPage.setTotal(1)
        replyPage.setRecords([replyComment])
        commentRepository.page(dto) >> page
        commentRepository.getReplyComment(_ as Long,1,3) >> replyPage
        commentLikeService.isLike(1, 1) >> true
        commentLikeService.checkIfLike(comment.getId(),dto.getUserId(),referenceId) >> false
        commentLikeService.checkIfLike(replyComment.getId(),dto.getUserId(),referenceId) >> false
        commentLikeService.getLikeSize(comment.getId(),referenceId) >> likeSize
        commentLikeService.getLikeSize(replyComment.getId(),referenceId) >> 0L
        when:
        def result = service.page(dto)
        then:
        result.getRecords().size() == 1
        result.getRecords().get(0).getLikeFlag() == false
        result.getRecords().get(0).getLikeSize() == likeSize
        result.getRecords().get(0).getReplyList().getRecords().size() ==1
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeFlag() == false
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeSize() == 0
    }

    def "page 一条评论，一条回复，评论有点赞且是当前用户点赞，回复无点赞"(){
        def likeSize = 30L
        given:
        def dto = new CommentQueryDTO()
        dto.setPage(1);
        dto.setSize(10);
        dto.setReferenceId(referenceId)
        dto.setUserId(5L)
        def comment = this.getComment(1L, 1L, 2L, null, referenceId)
        def replyComment = this.getReplyComment(2L, 2L, 1L, comment.getId(), referenceId)
        def page = new Page<Comment>()
        page.setTotal(1)
        page.setRecords([comment])
        def replyPage = new Page<Comment>()
        replyPage.setTotal(1)
        replyPage.setRecords([replyComment])
        commentRepository.page(dto) >> page
        commentRepository.getReplyComment(_ as Long,1,3) >> replyPage
        commentLikeService.isLike(1, 1) >> true
        commentLikeService.checkIfLike(comment.getId(),dto.getUserId(),referenceId) >> true
        commentLikeService.checkIfLike(replyComment.getId(),dto.getUserId(),referenceId) >> false
        commentLikeService.getLikeSize(comment.getId(),referenceId) >> likeSize
        commentLikeService.getLikeSize(replyComment.getId(),referenceId) >> 0L
        when:
        def result = service.page(dto)
        then:
        result.getRecords().size() == 1
        result.getRecords().get(0).getLikeFlag() == true
        result.getRecords().get(0).getLikeSize() == likeSize
        result.getRecords().get(0).getReplyList().getRecords().size() ==1
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeFlag() == false
        result.getRecords().get(0).getReplyList().getRecords().get(0).getLikeSize() == 0
    }

    def "addComment 类型为评论，传入父级评论id"(){
        given:
        def dto = new CommentAddDTO()
        dto.setReferenceId(referenceId)
        dto.setUserId(1L)
        dto.setContent("test")
        dto.setCommentId(1L)
        dto.setToUserId(2L)
        dto.setType(CommentTypeEnum.COMMENT.name())
        commentRepository.addComment(_ as Comment) >> 1L
        when:
        def result = service.addComment(dto)
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "参数错误！评论不可有父评论id！"
    }

    def "addComment 类型为回复或者回复评论，未传入父级评论id"(){
        given:
        def dto = new CommentAddDTO()
        dto.setReferenceId(referenceId)
        dto.setUserId(1L)
        dto.setContent("test")
        dto.setToUserId(2L)
        dto.setType(CommentTypeEnum.REPLY.name())
        commentRepository.addComment(_ as Comment) >> 1L
        when:
        def result = service.addComment(dto)
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "参数错误！评论id不能为空！"
    }

    def "addComment 类型为回复或者回复评论，父级评论不存在"(){
        given:
        def dto = new CommentAddDTO()
        dto.setReferenceId(referenceId)
        dto.setUserId(1L)
        dto.setContent("test")
        dto.setToUserId(2L)
        dto.setCommentId(1L)
        dto.setType(CommentTypeEnum.REPLY.name())
        commentRepository.addComment(_ as Comment) >> 1L
        when:
        commentRepository.getComment(dto.getCommentId()) >> null
        def result = service.addComment(dto)
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "回复评论不存在！"
    }

    def "addComment 成功"(){
        given:
        def dto = new CommentAddDTO()
        dto.setReferenceId(referenceId)
        dto.setUserId(1L)
        dto.setContent("test")
        dto.setToUserId(2L)
        dto.setCommentId(1L)
        dto.setType(CommentTypeEnum.REPLY.name())

        def comment = this.getComment(1L, 1L, 2L, null, referenceId)
        when:
        commentRepository.addComment(_ as Comment) >> 1L
        commentRepository.getComment(dto.getCommentId()) >> comment
        commentRepository.save(_ as Comment) >> true
        def result = service.addComment(dto)
        then:
        notThrown(SystemException)
        result == true
    }

    def "removeComment 评论不存在"(){
        given:
        def dto = new CommentRemoveDTO()
        dto.setCommentId(1L)
        dto.setUserId(1L)
        commentRepository.getComment(dto.getCommentId()) >> null
        when:
        def result = service.removeComment(dto.getUserId(),dto.getCommentId())
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "评论不存在！"
    }

    def "removeComment 用户不是当前评论创建用户"(){
        given:
        def dto = new CommentRemoveDTO()
        dto.setCommentId(1L)
        dto.setUserId(2L)
        def comment = this.getComment(dto.getCommentId(), 1L, 3L, null, referenceId)
        commentRepository.getComment(dto.getCommentId()) >> comment
        when:
        def result = service.removeComment(dto.getUserId(),dto.getCommentId())
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "您没有权限删除该评论！"
    }

    def "removeComment 删除评论大于一天"(){
        given:
        def dto = new CommentRemoveDTO()
        dto.setCommentId(1L)
        dto.setUserId(1L)
        def comment = this.getComment(dto.getCommentId(), dto.getUserId(), 3L, null, referenceId)
        commentRepository.getComment(dto.getCommentId()) >> comment
        def dateString = "2024-05-07 17:26:00"
        def format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        def date = format.parse(dateString)
        comment.setCreateTime(date)
        when:
        def result = service.removeComment(dto.getUserId(),dto.getCommentId())
        then:
        def throwable = thrown(SystemException)
        throwable.getMessage() == "您只能删除1天内发布的评论！"
    }

     Comment getReplyComment(Long commentId, Long userId, Long toUserId, Long rootId, Long referenceId) {
        Comment comment = new Comment();
        comment.setId(commentId);
        comment.setParentId(rootId);
        comment.setReferenceId(referenceId);
        comment.setUserId(userId);
        comment.setToUserId(toUserId);
        comment.setRootId(rootId);
        comment.setContent("test");
        comment.setType(CommentTypeEnum.COMMENT_REPLY.name());
        comment.setAuditStatus(AuditStatusEnum.PASS.name());
        comment.setCreateTime(new Date());
        return comment;
    }

    Comment getComment(Long commentId, Long userId, Long toUserId, Long rootId, Long referenceId) {
        Comment comment = new Comment();
        comment.setId(commentId);
        comment.setUserId(userId);
        comment.setToUserId(toUserId);
        comment.setRootId(rootId);
        comment.setReferenceId(referenceId);
        comment.setContent("test");
        comment.setType(CommentTypeEnum.COMMENT.name());
        comment.setAuditStatus(AuditStatusEnum.PASS.name());
        comment.setCreateTime(new Date());
        return comment;
    }
}